/*
 * Util.h
 *
 *  Created on: 2011-8-20
 *      Author: yong
 */

#ifndef UTIL_H_
#define UTIL_H_
#include <boost/algorithm/string/trim.hpp>
#include "Typedef.h"
namespace distrim
{
class Util
{
private:
	Util()
	{
	}
public:
	template<typename K, typename V1, typename V2>
	static void KeyValueToMatrix(const KeyValue<K, V1> &kv,
			boost::numeric::ublas::matrix<V2> &m)
	{
		std::copy(kv.begin(), kv.end(), m.begin2());
	}

	static size_t CountLines(const fs::path &p)
		{
			size_t lineCounter = 0;
			countPath(p, lineCounter);
			return lineCounter;
		}

	static void CountFile(const fs::path &p, size_t &lineCounter)
	{
		::boost::filesystem::ifstream ifs(p);
		if (!ifs)
		{
			BOOST_THROW_EXCEPTION(std::invalid_argument(std::string(
									"error opening file") + p.c_str()));
		}
		std::string lineStr;
		while (getline(ifs, lineStr))
		{
			if (!lineStr.empty() && lineStr[0] != '@')
			{
				++lineCounter;
			}
		}
	}

private:
	static void countDirectory(const fs::path &p, size_t &lineCounter)
	{
		fs::directory_iterator dirEnd;
		for (fs::directory_iterator dirIter(p); dirIter != dirEnd; ++dirIter)
		{
			if (fs::is_directory(*dirIter))
			{
				countDirectory(*dirIter, lineCounter);
			}
			else if (fs::is_regular_file(*dirIter))
			{
				CountFile(*dirIter, lineCounter);
			}
		}
	}

	static void countPath(const fs::path &p, size_t &lineCounter)
	{
		if (fs::is_regular_file(p))
		{
			CountFile(p, lineCounter);
		}
		else if (fs::is_directory(p))
		{
			countDirectory(p, lineCounter);
		}
	}
};

}

#endif /* UTIL_H_ */
